"""
Zabbix仪表板API
基于Zabbix API + ECharts实现动态图表系统
"""

from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework import status
from django.http import JsonResponse
from .models import ZabbixServer
from .utils.zabbix_api import ZabbixAPIManager
import json
import logging
import hashlib
from datetime import datetime, timedelta
from django.core.cache import cache

logger = logging.getLogger(__name__)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_host_groups(request):
    """获取主机组列表"""
    try:
        zabbix_server_id = request.GET.get('zabbix_server_id')

        if not zabbix_server_id:
            # 获取默认的活跃Zabbix服务器
            zabbix_server = ZabbixServer.objects.filter(is_active=True).first()
        else:
            zabbix_server = ZabbixServer.objects.filter(id=zabbix_server_id, is_active=True).first()

        if not zabbix_server:
            return Response({
                'success': False,
                'message': '没有找到活跃的Zabbix服务器'
            }, status=status.HTTP_400_BAD_REQUEST)

        zabbix_api = ZabbixAPIManager(zabbix_server)
        if not zabbix_api._connect():
            return Response({
                'success': False,
                'message': '连接Zabbix失败'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        # 获取主机组列表
        groups = zabbix_api.zapi.hostgroup.get(
            output=['groupid', 'name'],
            real_hosts=True,  # 只获取包含真实主机的组
            sortfield='name'
        )

        result = []
        for group in groups:
            result.append({
                'id': group['groupid'],
                'name': group['name']
            })

        return Response({
            'success': True,
            'data': result,
            'message': '获取主机组列表成功'
        })

    except Exception as e:
        logger.error(f"获取主机组列表失败: {e}")
        return Response({
            'success': False,
            'message': f'获取主机组列表失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_hosts_by_group(request):
    """根据主机组获取主机列表"""
    try:
        group_id = request.GET.get('group_id')
        zabbix_server_id = request.GET.get('zabbix_server_id')

        if not group_id:
            return Response({
                'success': False,
                'message': '请提供主机组ID'
            }, status=status.HTTP_400_BAD_REQUEST)

        if not zabbix_server_id:
            zabbix_server = ZabbixServer.objects.filter(is_active=True).first()
        else:
            zabbix_server = ZabbixServer.objects.filter(id=zabbix_server_id, is_active=True).first()

        if not zabbix_server:
            return Response({
                'success': False,
                'message': '没有找到活跃的Zabbix服务器'
            }, status=status.HTTP_400_BAD_REQUEST)

        zabbix_api = ZabbixAPIManager(zabbix_server)
        if not zabbix_api._connect():
            return Response({
                'success': False,
                'message': '连接Zabbix失败'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        # 获取主机列表
        hosts = zabbix_api.zapi.host.get(
            output=['hostid', 'host', 'name', 'status'],
            groupids=[group_id],
            sortfield='name'
        )

        result = []
        for host in hosts:
            result.append({
                'id': host['hostid'],
                'host': host['host'],
                'name': host['name'],
                'status': '在线' if host['status'] == '0' else '离线'
            })

        return Response({
            'success': True,
            'data': result,
            'message': '获取主机列表成功'
        })

    except Exception as e:
        logger.error(f"获取主机列表失败: {e}")
        return Response({
            'success': False,
            'message': f'获取主机列表失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_host_graphs(request):
    """获取主机的图表配置"""
    try:
        host_id = request.GET.get('host_id')
        zabbix_server_id = request.GET.get('zabbix_server_id')

        if not host_id:
            return Response({
                'success': False,
                'message': '请提供主机ID'
            }, status=status.HTTP_400_BAD_REQUEST)

        if not zabbix_server_id:
            zabbix_server = ZabbixServer.objects.filter(is_active=True).first()
        else:
            zabbix_server = ZabbixServer.objects.filter(id=zabbix_server_id, is_active=True).first()

        if not zabbix_server:
            return Response({
                'success': False,
                'message': '没有找到活跃的Zabbix服务器'
            }, status=status.HTTP_400_BAD_REQUEST)

        zabbix_api = ZabbixAPIManager(zabbix_server)
        if not zabbix_api._connect():
            return Response({
                'success': False,
                'message': '连接Zabbix失败'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        # 获取主机的图表
        graphs = zabbix_api.zapi.graph.get(
            output=['graphid', 'name', 'width', 'height'],
            hostids=[host_id],
            sortfield='name'
        )

        logger.info(f"获取到主机 {host_id} 的图表数量: {len(graphs)}")
        for graph in graphs:
            logger.info(f"图表: {graph['name']} (ID: {graph['graphid']})")

        result = []
        for graph in graphs:
            # 获取图表的监控项
            graph_items = zabbix_api.zapi.graphitem.get(
                output=['itemid', 'color', 'calc_fnc', 'type'],
                graphids=[graph['graphid']]
            )

            # 获取监控项详情
            item_ids = [item['itemid'] for item in graph_items]
            items = zabbix_api.zapi.item.get(
                output=['itemid', 'name', 'key_', 'units', 'value_type'],
                itemids=item_ids
            ) if item_ids else []

            result.append({
                'id': graph['graphid'],
                'name': graph['name'],
                'width': int(graph['width']),
                'height': int(graph['height']),
                'items': items,
                'graph_items': graph_items
            })

        return Response({
            'success': True,
            'data': result,
            'message': '获取图表配置成功'
        })

    except Exception as e:
        logger.error(f"获取图表配置失败: {e}")
        return Response({
            'success': False,
            'message': f'获取图表配置失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_graph_data(request):
    """获取图表的历史数据"""
    try:
        graph_id = request.GET.get('graph_id')
        time_from = request.GET.get('time_from', 'now-6h')
        time_to = request.GET.get('time_to', 'now')
        zabbix_server_id = request.GET.get('zabbix_server_id')

        if not graph_id:
            return Response({
                'success': False,
                'message': '请提供图表ID'
            }, status=status.HTTP_400_BAD_REQUEST)

        # 生成缓存键
        cache_key = f"graph_data_{graph_id}_{time_from}_{time_to}_{zabbix_server_id or 'default'}"
        cache_key = hashlib.md5(cache_key.encode()).hexdigest()

        # 尝试从缓存获取数据
        cached_data = cache.get(cache_key)
        if cached_data:
            logger.info(f"从缓存获取图表数据: {graph_id}")
            return Response({
                'success': True,
                'data': cached_data,
                'message': '获取图表数据成功 (缓存)',
                'cached': True
            })

        if not zabbix_server_id:
            zabbix_server = ZabbixServer.objects.filter(is_active=True).first()
        else:
            zabbix_server = ZabbixServer.objects.filter(id=zabbix_server_id, is_active=True).first()

        if not zabbix_server:
            return Response({
                'success': False,
                'message': '没有找到活跃的Zabbix服务器'
            }, status=status.HTTP_400_BAD_REQUEST)

        zabbix_api = ZabbixAPIManager(zabbix_server)
        if not zabbix_api._connect():
            return Response({
                'success': False,
                'message': '连接Zabbix失败'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        # 转换时间格式
        if time_from.startswith('now-'):
            hours = int(time_from.replace('now-', '').replace('h', ''))
            time_from_ts = int((datetime.now() - timedelta(hours=hours)).timestamp())
        else:
            time_from_ts = int(time_from)

        time_to_ts = int(datetime.now().timestamp())

        # 获取图表的监控项
        graph_items = zabbix_api.zapi.graphitem.get(
            output=['itemid', 'color'],
            graphids=[graph_id]
        )

        result = {
            'graph_id': graph_id,
            'time_from': time_from_ts,
            'time_to': time_to_ts,
            'series': []
        }

        for graph_item in graph_items:
            item_id = graph_item['itemid']

            # 获取监控项信息
            items = zabbix_api.zapi.item.get(
                output=['name', 'units', 'value_type'],
                itemids=[item_id]
            )

            if not items:
                continue

            item = items[0]
            value_type = int(item['value_type'])

            # 只处理数值类型的监控项
            if value_type in [0, 3]:  # 数值类型
                history = zabbix_api.zapi.history.get(
                    itemids=[item_id],
                    time_from=time_from_ts,
                    time_till=time_to_ts,
                    output='extend',
                    sortfield='clock',
                    limit=1000
                )

                data_points = []
                for h in history:
                    timestamp = int(h['clock']) * 1000  # ECharts需要毫秒时间戳
                    value = float(h['value']) if h['value'].replace('.', '').replace('-', '').isdigit() else 0
                    data_points.append([timestamp, value])

                result['series'].append({
                    'name': item['name'],
                    'data': data_points,
                    'color': f"#{graph_item['color']}",
                    'units': item['units']
                })

        # 缓存数据，根据时间范围设置不同的缓存时间
        if time_from.startswith('now-'):
            # 相对时间，缓存时间较短
            cache_timeout = 60  # 1分钟
        else:
            # 绝对时间，缓存时间较长
            cache_timeout = 300  # 5分钟

        cache.set(cache_key, result, cache_timeout)
        logger.info(f"缓存图表数据: {graph_id}, 缓存时间: {cache_timeout}秒")

        return Response({
            'success': True,
            'data': result,
            'message': '获取图表数据成功',
            'cached': False
        })

    except Exception as e:
        logger.error(f"获取图表数据失败: {e}")
        return Response({
            'success': False,
            'message': f'获取图表数据失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def create_graph(request):
    """创建Zabbix图表"""
    try:
        data = request.data
        graph_name = data.get('name')
        host_id = data.get('host_id')
        item_ids = data.get('item_ids', [])
        width = data.get('width', 900)
        height = data.get('height', 200)
        zabbix_server_id = data.get('zabbix_server_id')

        if not graph_name or not host_id or not item_ids:
            return Response({
                'success': False,
                'message': '请提供图表名称、主机ID和监控项ID列表'
            }, status=status.HTTP_400_BAD_REQUEST)

        if not zabbix_server_id:
            zabbix_server = ZabbixServer.objects.filter(is_active=True).first()
        else:
            zabbix_server = ZabbixServer.objects.filter(id=zabbix_server_id, is_active=True).first()

        if not zabbix_server:
            return Response({
                'success': False,
                'message': '没有找到活跃的Zabbix服务器'
            }, status=status.HTTP_400_BAD_REQUEST)

        zabbix_api = ZabbixAPIManager(zabbix_server)
        if not zabbix_api._connect():
            return Response({
                'success': False,
                'message': '连接Zabbix失败'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        # 准备图表项数据
        gitems = []
        colors = ['FF0000', '00FF00', '0000FF', 'FFFF00', 'FF00FF', '00FFFF']  # 预定义颜色

        for i, item_id in enumerate(item_ids):
            gitems.append({
                'itemid': item_id,
                'color': colors[i % len(colors)],
                'calc_fnc': 2,  # 平均值
                'type': 0,      # 简单图形
                'periods_cnt': 5
            })

        # 创建图表
        result = zabbix_api.zapi.graph.create({
            'name': graph_name,
            'width': width,
            'height': height,
            'gitems': gitems
        })

        if result and 'graphids' in result:
            graph_id = result['graphids'][0]

            return Response({
                'success': True,
                'data': {
                    'graph_id': graph_id,
                    'name': graph_name,
                    'width': width,
                    'height': height
                },
                'message': '创建图表成功'
            })
        else:
            return Response({
                'success': False,
                'message': '创建图表失败'
            }, status=status.HTTP_400_BAD_REQUEST)

    except Exception as e:
        logger.error(f"创建图表失败: {e}")
        return Response({
            'success': False,
            'message': f'创建图表失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_host_items(request):
    """获取主机的监控项列表"""
    try:
        host_id = request.GET.get('host_id')
        zabbix_server_id = request.GET.get('zabbix_server_id')

        if not host_id:
            return Response({
                'success': False,
                'message': '请提供主机ID'
            }, status=status.HTTP_400_BAD_REQUEST)

        if not zabbix_server_id:
            zabbix_server = ZabbixServer.objects.filter(is_active=True).first()
        else:
            zabbix_server = ZabbixServer.objects.filter(id=zabbix_server_id, is_active=True).first()

        if not zabbix_server:
            return Response({
                'success': False,
                'message': '没有找到活跃的Zabbix服务器'
            }, status=status.HTTP_400_BAD_REQUEST)

        zabbix_api = ZabbixAPIManager(zabbix_server)
        if not zabbix_api._connect():
            return Response({
                'success': False,
                'message': '连接Zabbix失败'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        # 获取监控项列表
        items = zabbix_api.zapi.item.get(
            output=['itemid', 'name', 'key_', 'units', 'value_type', 'status'],
            hostids=[host_id],
            filter={'status': 0, 'value_type': [0, 3]},  # 只获取启用的数值类型监控项
            sortfield='name'
        )

        result = []
        for item in items:
            result.append({
                'id': item['itemid'],
                'name': item['name'],
                'key': item['key_'],
                'units': item['units'],
                'value_type': item['value_type']
            })

        return Response({
            'success': True,
            'data': result,
            'message': '获取监控项列表成功'
        })

    except Exception as e:
        logger.error(f"获取监控项列表失败: {e}")
        return Response({
            'success': False,
            'message': f'获取监控项列表失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
